]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
Fix updating last visited time for the doc display items.
authorMarina Zhurakhinskaya <marinaz@redhat.com>
Wed, 22 Jul 2009 22:57:05 +0000 (18:57 -0400)
committerMarina Zhurakhinskaya <marinaz@redhat.com>
Wed, 22 Jul 2009 22:57:05 +0000 (18:57 -0400)
Make sure that we calculate the next update time correctly.

Store timeout time instead of the timeout delta, so that it doesn't get outdated.

Create a new callback when the time update happens for the original callback.

Make sure last visited time is updated in the details pane by keeping track
of the description actors created for the detail actors.

Add comments to the new functions.

js/ui/docDisplay.js
js/ui/genericDisplay.js
src/shell-global.c

index e7a82808c301fed4600e1cfbfa53ff612b7e6719..c507e67b5e36e433ca6f8a5379c2f8e978424475 100644 (file)
@@ -13,6 +13,8 @@ const GenericDisplay = imports.ui.genericDisplay;
 const Main = imports.ui.main;
 
 /* This class represents a single display item containing information about a document.
+ * We take the current number of seconds in the constructor to avoid looking up the current
+ * time for every item when they are created in a batch.
  *
  * docInfo - DocInfo object containing information about the document
  * currentSeconds - current number of seconds since the epoch
@@ -28,17 +30,17 @@ DocDisplayItem.prototype = {
     _init : function(docInfo, currentSecs, availableWidth) {
         GenericDisplay.GenericDisplayItem.prototype._init.call(this, availableWidth);
         this._docInfo = docInfo;
-
+       
         this._setItemInfo(docInfo.name, "");
-        // We take the current number of seconds here to avoid looking up the current
-        // time for every item
+
+        this._timeoutTime = -1;
         this._resetTimeDisplay(currentSecs);
     },
 
     //// Public methods ////
 
-    getUpdateTimeout: function() {
-        return this._timeout;
+    getUpdateTimeoutTime: function() {
+        return this._timeoutTime;
     },
 
     // Update any relative-time based displays for this item.
@@ -78,11 +80,12 @@ DocDisplayItem.prototype = {
 
     //// Private Methods ////
 
+    // Updates the last visited time displayed in the description text for the item. 
     _resetTimeDisplay: function(currentSecs) {
         let lastSecs = this._docInfo.lastVisited().getTime() / 1000;
         let timeDelta = currentSecs - lastSecs;
         let [text, nextUpdate] = Shell.Global.get().format_time_relative_pretty(timeDelta);
-        this._timeout = nextUpdate;
+        this._timeoutTime = currentSecs + nextUpdate;
         this._setDescriptionText(text);
     }
 };
@@ -103,7 +106,12 @@ DocDisplay.prototype = {
         GenericDisplay.GenericDisplay.prototype._init.call(this, width);
         let me = this;
 
-        this._updateTimeoutTarget = -1;
+        // We keep a single timeout callback for updating last visited times
+        // for all the items in the display. This avoids creating individual
+        // callbacks for each item in the display. So proper time updates
+        // for individual items and item details depend on the item being 
+        // associated with one of the displays.
+        this._updateTimeoutTargetTime = -1;
         this._updateTimeoutId = 0;
 
         this._docManager = DocInfo.getDocManager(GenericDisplay.ITEM_DISPLAY_ICON_SIZE);
@@ -198,25 +206,37 @@ DocDisplay.prototype = {
     // Creates a DocDisplayItem based on itemInfo, which is expected to be a DocInfo object.
     _createDisplayItem: function(itemInfo, width) {
         let currentSecs = new Date().getTime() / 1000;
-        let doc = new DocDisplayItem(itemInfo, currentSecs, width);
-        let timeout = Math.round(doc.getUpdateTimeout() / 8)+1;
-        if (this._updateTimeoutTarget < 0 || timeout < this._updateTimeoutTarget) {
-            if (this._updateTimeoutId > 0)
-                Mainloop.source_remove(this._updateTimeoutId);
-            this._updateTimeoutId = Mainloop.timeout_add_seconds(timeout, Lang.bind(this, this._docTimeout));
-            this._updateTimeoutTarget = doc.getUpdateTimeout();
-        }
-        return doc;
+        let docDisplayItem = new DocDisplayItem(itemInfo, currentSecs, width);
+        this._updateTimeoutCallback(docDisplayItem, currentSecs);
+        return docDisplayItem;
     },
 
     //// Private Methods ////
+
+    // A callback function that redisplays the items, updating their descriptions,
+    // and sets up a new timeout callback.
     _docTimeout: function () {
         let currentSecs = new Date().getTime() / 1000;
+        this._updateTimeoutId = 0;
+        this._updateTimeoutTargetTime = -1;
         for (let docId in this._displayedItems) {
-            let disp = this._displayedItems[docId];
-            disp.redisplay(currentSecs);
+            let docDisplayItem = this._displayedItems[docId];
+            docDisplayItem.redisplay(currentSecs);          
+            this._updateTimeoutCallback(docDisplayItem, currentSecs);
         }
         return true;
+    },
+
+    // Updates the timeout callback if the timeout time for the docDisplayItem 
+    // is earlier than the target time for the current timeout callback.
+    _updateTimeoutCallback: function (docDisplayItem, currentSecs) {
+        let timeoutTime = docDisplayItem.getUpdateTimeoutTime();
+        if (this._updateTimeoutTargetTime < 0 || timeoutTime < this._updateTimeoutTargetTime) {
+            if (this._updateTimeoutId > 0)
+                Mainloop.source_remove(this._updateTimeoutId);
+            this._updateTimeoutId = Mainloop.timeout_add_seconds(timeoutTime - currentSecs, Lang.bind(this, this._docTimeout));
+            this._updateTimeoutTargetTime = timeoutTime;
+        }
     }
 };
 
index 27b3bffb5e6878857f661de5fe11d6c9fc9df16f..7d7533890ba22528075d2ad2e3049df2cd8b5c27 100644 (file)
@@ -116,6 +116,11 @@ GenericDisplayItem.prototype = {
         this._icon = null;
         this._previewIcon = null; 
 
+        // An array of details description actors that we create over time for the item.
+        // It is used for updating the description text inside the details actor when
+        // the description text for the item is updated.
+        this._detailsDescriptions = [];
+
         this.dragActor = null;
     },
 
@@ -201,6 +206,8 @@ GenericDisplayItem.prototype = {
                                                     text: this._description.text });
         textDetails.append(detailsDescription, Big.BoxPackFlags.NONE);
 
+        this._detailsDescriptions.push(detailsDescription);
+
         mainDetails.append(textDetails, Big.BoxPackFlags.EXPAND);
 
         this._ensurePreviewIconCreated();
@@ -287,8 +294,16 @@ GenericDisplayItem.prototype = {
         this.actor.add_actor(this._description);
     },
 
+    // Sets the description text for the item, including the description text
+    // in the details actors that have been created for the item. 
     _setDescriptionText: function(text) {
         this._description.text = text;
+        for (let i = 0; i < this._detailsDescriptions.length; i++) {
+            let detailsDescription = this._detailsDescriptions[i];
+            if (detailsDescription != null) {
+                detailsDescription.text = text;
+            }
+        }
     },
 
     //// Virtual protected methods ////
index 19ff88ac2211270148c36057a747899ebce62ac5..8429cd1afd12aaff6edb1c1d5d91b8aad25e881c 100644 (file)
@@ -973,6 +973,8 @@ root_pixmap_destroy (GObject *sender, gpointer data)
  *
  * Format a time value for human consumption only.  The passed time
  * value is a delta in terms of seconds from the current time.
+ * This function needs to be in C because of its use of ngettext() which
+ * is not accessible from JavaScript.
  */
 void
 shell_global_format_time_relative_pretty (ShellGlobal *global,
@@ -989,16 +991,16 @@ shell_global_format_time_relative_pretty (ShellGlobal *global,
     *next_update = MINUTE - delta;
    } else if (delta < HOUR) {
      *text = g_strdup_printf (ngettext ("%d minute ago", "%d minutes ago", delta / MINUTE), delta / MINUTE);
-     *next_update = MINUTE*(delta-MINUTE + 1) - delta;
+     *next_update = MINUTE - (delta % MINUTE);
    } else if (delta < DAY) {
      *text = g_strdup_printf (ngettext ("%d hour ago", "%d hours ago", delta / HOUR), delta / HOUR);
-     *next_update = HOUR*(delta-HOUR + 1) - delta;
+     *next_update = HOUR - (delta % HOUR);
    } else if (delta < WEEK) {
      *text = g_strdup_printf (ngettext ("%d day ago", "%d days ago", delta / DAY), delta / DAY);
-     *next_update = DAY*(delta-DAY + 1) - delta;
+     *next_update = DAY - (delta % DAY);
    } else {
      *text = g_strdup_printf (ngettext ("%d week ago", "%d weeks ago", delta / WEEK), delta / WEEK);
-     *next_update = WEEK*(delta-WEEK + 1) - delta;
+     *next_update = WEEK - (delta % WEEK);
    }
 }